package cn.yogehaoren.badfox.spring.common;


import cn.yogehaoren.badfox.Constants;
import cn.yogehaoren.badfox.spring.boot.BadFoxProperties;
import cn.yogehaoren.badfox.core.BadFoxProcessor;
import cn.yogehaoren.badfox.core.BadFoxQueue;
import cn.yogehaoren.badfox.def.BaseBadFox;
import cn.yogehaoren.badfox.exception.BadFoxBeanResolveException;
import cn.yogehaoren.badfox.struct.CrawlerModel;
import cn.yogehaoren.badfox.utils.StrFormatUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.util.CollectionUtils;

import java.util.concurrent.Executors;


public class BadFoxBootstrapListener implements ApplicationListener<ContextRefreshedEvent> {



    public BadFoxBootstrapListener(){
        super();
    }

    public BadFoxBootstrapListener(boolean isSpringBoot) {
        super();
    }

    private Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * Handle an application event.
     *
     * @param event the event to respond to
     */
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        ApplicationContext context = event.getApplicationContext();

        BadFoxProperties crawlerProperties = context.getBean(BadFoxProperties.class);

        if (!crawlerProperties.isEnabled()){
            logger.warn("{} is not enabled", Constants.BAD_FOX_ENABLED);
            return;
        }


        if (context != null) {
            if (CollectionUtils.isEmpty(BadFoxCache.getCrawlers())) {
                logger.info("Not find any crawler,may be you need to check.");
                return;
            }

            int threadPoolSize = -1;
            if(crawlerProperties.getThreadPoolSize() > 0){
                threadPoolSize = (int)crawlerProperties.getThreadPoolSize();
            }else {
                threadPoolSize = 2* Runtime.getRuntime().availableProcessors() ;
            }


            BadFoxCache.setThreadPool(Executors.newFixedThreadPool(threadPoolSize));



            for (Class<? extends BaseBadFox> a : BadFoxCache.getCrawlers()) {
                CrawlerModel crawlerModel = new CrawlerModel(a, context);
                if (BadFoxCache.isExist(crawlerModel.getCrawlerName())) {
                    logger.error("Crawler:{} is repeated,please check", crawlerModel.getCrawlerName());
                    throw new BadFoxBeanResolveException(StrFormatUtil.info("Crawler:{} is repeated,please check", crawlerModel.getCrawlerName()));
                }
                BadFoxCache.putCrawlerModel(crawlerModel.getCrawlerName(), crawlerModel);
                if(crawlerModel.isAutoStart()){
                    crawlerModel.startRequest();
                    logger.info("auto start fox: {}", crawlerModel.getCrawlerName());
                }


            }


            for (int i = 0; i < threadPoolSize; i++) {
                BadFoxCache.getThreadPool().execute(new BadFoxProcessor());
            }

        }
    }
}
